#ifndef _ZSTRINGS_H_
#define _ZSTRINGS_H_

//#include "stdafx.h"
#include <stdlib.h>
#include "utstrings.h"

#define ZSTRING_DEFAULT_SIZE		256

class mystring
{
	char *lpbuf;
	unsigned long bufsize;
	unsigned long len;

public:
	mystring()
	{
		len = 0;
		lpbuf = (char*) zalloc(ZSTRING_DEFAULT_SIZE);
		if(lpbuf)
		{
			lpbuf[0] = '\0';
			bufsize = ZSTRING_DEFAULT_SIZE;
		}
		else
		{
			lpbuf = NULL;
			bufsize = 0;
		}
	}

	mystring(char *lpstr)
	{
		len = strlen(lpstr);
		bufsize = (len > 0)?(len+1):ZSTRING_DEFAULT_SIZE;
		lpbuf = (char*) zalloc(bufsize);
		if(lpbuf)
		{
			strcpy(lpbuf, lpstr);
		}
		else
		{
			lpbuf = NULL;
			bufsize = 0;
			len = 0;
		}
	}

	mystring(unsigned long size)
	{
		bufsize = size;
		len = 0;
		if(bufsize > 0)
		{
			lpbuf = (char*) zalloc(bufsize);
			if(lpbuf)
			{
				lpbuf[0] = '\0';
			}
			else
			{
				lpbuf = NULL;
				bufsize = 0;
			}
		}
		else
		{
			lpbuf = NULL;
		}
	}

	~mystring()
	{
		//printf("destroy...\r\n");
		if(isalloc(lpbuf))
		{
			zfree(lpbuf);
		}
	}

	unsigned long lenght() const
	{
		return len;
	}

	unsigned long buffersize() const
	{
		return bufsize;
	}

	char *c_str() const
	{
		return lpbuf?lpbuf:nullstring;
	}

	char *buffer() const
	{
		return lpbuf;
	}

	mystring& operator = (char chr)
	{
		if(bufsize >= 2 || resize(2))
		{
			lpbuf[0] = chr;
			lpbuf[1] = '\0';
			len = 1;
		}

		return *this;
	}

	mystring& operator = (char *lpstr)
	{
		unsigned long sl;
		sl = strlen(lpstr);
		if(sl < bufsize || resize(sl+1))
		{
			strcpy(lpbuf, lpstr);
			len = sl;
		}

		return *this;
	}

	mystring& operator = (int num)
	{
		//unsigned long sl;
		if(bufsize >= 34 || resize(34))
		{
			itoa(num, lpbuf, 10);
			len = strlen(lpbuf);
		}

		return *this;
	}

	mystring& operator = (unsigned long num)
	{
		//unsigned long sl;
		if(bufsize >= 34 || resize(34))
		{
			ultoa(num, lpbuf, 10);
			len = strlen(lpbuf);
		}

		return *this;
	}

	mystring& operator += (char *lpstr)
	{
		unsigned long sl;
		sl = len + strlen(lpstr);
		if((sl < bufsize) || resize(sl+1))
		{
			strcat(lpbuf, lpstr);
			len = sl;
		}

		return *this;
	}

	mystring& operator += (int num)
	{
		if((bufsize >= len+34) || resize(len+34))
		{
			itoa(num, lpbuf+len, 34);
			len += strlen(lpbuf+len);
		}

		return *this;
	}

	mystring& operator += (unsigned long num)
	{
		if((bufsize >= len+34) || resize(len+34))
		{
			ultoa(num, lpbuf+len, 10);
			len += strlen(lpbuf+len);
		}

		return *this;
	}

	mystring& operator += (char chr)
	{
		if(((len+1) < bufsize) || resize(bufsize+1))
		{
			lpbuf[len] = chr;
			lpbuf[len+1] = '\0';
			len++;
		}

		return *this;
	}

	char operator[] (unsigned long pos) const
	{
		if(pos <= len)
		{
			return lpbuf[pos];
		}

		return 0;
	}

	int resize(unsigned long size)
	{
		void *newbuf;

		if(size > bufsize && (size - bufsize) < ZSTRING_DEFAULT_SIZE)
		{
			size = bufsize + ZSTRING_DEFAULT_SIZE;
		}

		newbuf = zalloc(size);
		if(newbuf)
		{
			memcpy(newbuf, lpbuf, bufsize);
			zfree(lpbuf);
			lpbuf = (char *) newbuf;
			bufsize = size;
			return -1;
		}
		else
		{
			return 0;
		}
	}

	unsigned long recalclen()
	{
		if(isalloc(lpbuf))
		{
			len = strlen(lpbuf);
		}
		else
		{
			len = 0;
			bufsize = 0;
		}

		return len;
	}

    void setdata(char *data, unsigned long datalen, unsigned long datasize)
    {
    	if(isalloc(data))
    	{
    		if(isalloc(lpbuf))
    		{
    			zfree(lpbuf);
    		}

    		len = datalen;
    		bufsize = datasize;
    		lpbuf = data;
    	}
    }

	void setdata(char *data)
    {
    	if(isalloc(data))
    	{
    		if(isalloc(lpbuf))
    		{
    			zfree(lpbuf);
    		}

    		len = strlen(data);
    		bufsize = len+1;
    		lpbuf = data;
    	}
    }
};

/*
int _tmain(int argc, _TCHAR* argv[])
{
	mystring ms;
	ms = "hello";
	ms = 'h';
	ms += " world!";
	printf("--APP: [%d] %s\r\n", ms.lenght(), ms.c_str());
	ms = "new lo";
	for(int i = 0; i < 10; i++)
	{
		ms += 'o';
	}
	ms += "ng world!";
	printf("--APP: [%d] %s\r\n", ms.lenght(), ms.c_str());
	ms += " hack";
	return 0;
}
/**/

#endif //_ZSTRINGS_H_
